home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Freeware / Read It Later 0.9924 / read_it_later-0.9924-fx.xpi / chrome / isreaditlater.jar / content / ISRIL.js < prev    next >
Text File  |  2008-11-02  |  37KB  |  1,115 lines

  1. function ISRILmaster()
  2. {
  3.     // -- Version Information -- //
  4.     this.v    = '0.9920';
  5.     this.cl = 'http://www.ideashower.com/blog/read-it-later-099-released/'; //changelog address
  6.     this.appId = 'isreaditlater';
  7.     
  8.     // -- Init Settings -- //    
  9.     this.inited = false;
  10.     
  11.     
  12.     // -- Defining Starting Variables -- //
  13.     this.listDrops                 = new Array();    
  14.     this.adding                 = false;    
  15.     this.ClickModeNodesN             = 0;
  16.     this.channels                = new Object();
  17.     
  18.     
  19.     // -- General Settings -- //
  20.     this.autoMarkWait = 5; //seconds
  21.     
  22. }
  23.  
  24.  
  25. ISRILmaster.prototype = {
  26.     
  27.     // --- Folder --- //
  28.     
  29.     loadFolder : function() {
  30.         if (ISRILprefs.prefIsSet('folderId') && ISRIL.folderExists(ISRILprefs.pref('folderGUID')) ) { 
  31.             ISRILglobals.folderId = ISRILprefs.pref('folderId');
  32.         } else {
  33.             //do a quick look to find a folder called 'Read It Later'
  34.             var folders = ISRIL.GetAllFolders();
  35.             for(i in folders) { 
  36.                 if (folders[i] && folders[i].node && folders[i].node.title == 'Read It Later') {
  37.                     ISRILglobals.folderId = folders[i].node.itemId;
  38.                     var newFolder = true;
  39.                     break;
  40.                 }
  41.             }
  42.             
  43.             if (!newFolder) {
  44.                 //Create New Folder
  45.                 ISRILglobals.folderId = ISRIL.sBookmarks.createFolder(
  46.                       ISRIL.sBookmarks.bookmarksMenuFolder,         // The id of the folder the new folder will be placed in.
  47.                       "Read It Later",               // The title of the new folder.
  48.                       ISRIL.sBookmarks.DEFAULT_INDEX);        // The position of the new folder in it's parent folder.
  49.             }
  50.  
  51.             ISRILprefs.setPref('folderId', ISRILglobals.folderId);
  52.             ISRILprefs.setPref('folderGUID', ISRIL.sBookmarks.getItemGUID( ISRILglobals.folderId ));
  53.             
  54.             ISRILsync.getUpdatesStart(true);
  55.         }
  56.     },
  57.     
  58.     folderExists : function(id) {
  59.         return ( (ISRIL.sBookmarks.getItemIdForGUID( id ) == -1) ? (false):(true) );
  60.     },
  61.     
  62.     saveNewFolder : function(id) {
  63.         ISRILprefs.setPref('folderId',    id );    
  64.         ISRILprefs.setPref('folderGUID', ISRIL.sBookmarks.getItemGUID( id ));
  65.         ISRIL.loadFolder();
  66.         //ISRILsync.sendFolder(); //Let them manually sync as not to duplicate old items
  67.         ISRILglobals.CacheStale = true;
  68.     },
  69.     
  70.     
  71.     // --- Get Vars --- //
  72.     
  73.     url : function() {
  74.         return ( (!getBrowser().currentURI.spec) ? (false):(getBrowser().currentURI.spec) );
  75.     },
  76.     title : function() {
  77.         return getBrowser().contentDocument.title;
  78.     },
  79.     uri : function(uri) {                
  80.         return ISRIL.ios.newURI(uri, null, null);    
  81.     },
  82.     
  83.     
  84.     // --- On Page Load --- //
  85.     
  86.     checkLoad : function(e) {
  87.         if (e.originalTarget instanceof HTMLDocument) {
  88.             var doc = e.originalTarget;
  89.             if (e.originalTarget.defaultView.frameElement) {
  90.               // Frame within a tab was loaded. doc should be the root document of
  91.               // the frameset. If you don't want do anything when frames/iframes
  92.               // are loaded in this web page, uncomment the following line:
  93.                return false;
  94.             }
  95.             ISRIL.checkPage();
  96.         }
  97.       },
  98.     
  99.     checkPage : function() {
  100.         if (ISRIL.url() != 'about:blank') {
  101.             var Search = ISRIL.findItem();
  102.  
  103.             if (Search[0] && Search[1] == 1 && !navigator.onLine) { ISRILoffline.Serve( Search[0] ); }
  104.             
  105.             //check url against...
  106.             ISRILgr.check();
  107.             
  108.             return ISRILxul.SetBtn( ((Search[0])?(2):(1)) );
  109.           }
  110.         return ISRILxul.SetBtn();
  111.       },
  112.     
  113.     findItem : function() {
  114.         var id = false;
  115.         var type = false;
  116.         
  117.         if (!navigator.onLine && decodeURI( ISRIL.url() ).match(new RegExp(ISRILoffline.prefix + '([0-9]+)'))) {
  118.             try {
  119.                 var i = RegExp.$1;
  120.                 if ( ISRIL.sBookmarks.getBookmarkURI(i).spec ) {
  121.                     id = ( (i != -1) ? (i):(null) );
  122.                     type = 2;
  123.                 }
  124.             } catch(e) {
  125.                 //item no longer exists (probably was marked as read in offline mode
  126.             }
  127.         } else {
  128.             id = ISRIL.InList( ISRIL.url() );
  129.             type = 1;
  130.         }
  131.         return new Array(id,type);
  132.     },
  133.     
  134.     // --- List Management --- //
  135.     
  136.     Save : function(url, title, nosync) {
  137.         
  138.         //If Read It Later Folder Doesn't Exist, prompt for a new folder.
  139.         if (!ISRILprefs.prefIsSet('folderId') || !ISRIL.folderExists(ISRILprefs.pref('folderGUID')) ) { 
  140.                         
  141.             var list = new Array( ISRIL.l('CreateOne')+'...' );
  142.             var selected = {};
  143.             
  144.             folders = ISRIL.GetAllFolders();
  145.             for(i in folders) {
  146.                 list.push( folders[i].node.title );
  147.             }
  148.             
  149.             var ok = ISRIL.sPrompts.select(window, ISRIL.l('ReadItLater'), ISRIL.l('NoFolder'), 
  150.                         (list.length < 7)?list.length:7, list, selected);
  151.             
  152.             if (ok) {
  153.                 if (selected.value == 0) {
  154.                     ISRIL.loadFolder();
  155.                 } else {                    
  156.                     ISRIL.saveNewFolder( folders[selected.value-1].node.itemId );
  157.                 }
  158.             } else {
  159.                 return false;    
  160.             }
  161.         }
  162.         
  163.         // -- Default Variables
  164.         
  165.         //If url was not sent, then assume it's the page we're on and that it was saved via checkmark
  166.         if (!url) { 
  167.             url = ISRIL.url();
  168.             var fromCheckmark = true;
  169.         }
  170.         if (!title) { title = ISRIL.title(); }
  171.         
  172.         // -- Attempt to add        
  173.         if (!ISRIL.InList(url)) {
  174.             //Check that it's a website and not local or ftp, etc
  175.             parsed = ISRIL.parseUri(url);
  176.             if (parsed.protocol == 'http' || parsed.protocol == 'https') {
  177.                 
  178.                 ISRILglobals.adding = true; //start
  179.                 
  180.                 //Add Bookmark
  181.                 bookmarkId = ISRIL.sBookmarks.insertBookmark(
  182.                   ISRILglobals.folderId,         // The id of the folder the bookmark will be placed in.
  183.                   ISRIL.uri(url),                     // The URI of the bookmark - an nsIURI object.
  184.                   ISRIL.sBookmarks.DEFAULT_INDEX,     // The position of the bookmark in it's parent folder.
  185.                   title);                    // The title of the bookmark.                
  186.                 
  187.                 //Add Auto-tags
  188.                 if (ISRILprefs.pref('auto-tags').length > 0) {
  189.                     ISRIL.sTags.tagURI( ISRIL.uri(url), ISRILprefs.pref('auto-tags').split(','), 1 ); //add all tags    
  190.                 }
  191.                 
  192.                 
  193.                 //Prepare to Sync
  194.                 if (!nosync) {ISRILsync.QueueNew( bookmarkId ); }                
  195.                 
  196.                 ISRILglobals.adding = false; //end                
  197.                 
  198.                 
  199.                 ISRIL.ListSizeInc(1); 
  200.     
  201.                 ISRIL.checkPage();
  202.                 
  203.                 if (fromCheckmark) {
  204.                     if (ISRILprefs.prefB('autoOffline')) {
  205.                         ISRILoffline.saveDoc( getBrowser().contentDocument , bookmarkId); //skip download queue since doc is already open
  206.                     }
  207.                     if ( ISRILprefs.prefB('auto-close-tab')) {
  208.                         gBrowser.removeCurrentTab();
  209.                     }
  210.                 }
  211.                 
  212.                 return bookmarkId;
  213.             
  214.             } else {                
  215.                 
  216.                 ISRILxul.sPrompt.alert(window, ISRIL.l('ReadItLater'), ISRIL.l('OnlyWebsites') );
  217.                 
  218.             }
  219.             
  220.         }
  221.         return false;
  222.     },
  223.     
  224.     SaveLink : function(url, title) {
  225.         url = ( (!url && gContextMenu) ? (gContextMenu.linkURL):(url) );
  226.         title = ( (!title && gContextMenu) ? (gContextMenu.linkText()):(title) );
  227.         bookmarkId = ISRIL.Save(url, title, true);
  228.         if (bookmarkId) {
  229.             
  230.             //if (ISRILprefs.prefB('autoOffline')) {
  231.             //    ISRILoffline.addToQueue( bookmarkId, true );
  232.             //} else {
  233.             //    ISRIL.ResolveLink(url, ISRIL.SaveLinkBack, bookmarkId);
  234.             //}
  235.             ISRIL.ResolveLink(url, ISRIL.SaveLinkBack, bookmarkId, true);
  236.             
  237.         }        
  238.         ISRILsync.QueueNew( bookmarkId , url, ISRILsync.syncTimeWaitResolve );
  239.         
  240.         //Save original URL in resolver
  241.         var sql = "REPLACE INTO ril_link_resolver (id, original_url) VALUES (?1, ?2)"
  242.         var statement = ISRIL.DB.createStatement(sql);
  243.             statement.bindInt32Parameter(0, bookmarkId);
  244.             statement.bindUTF8StringParameter(1, url);    
  245.             statement.execute();    
  246.             statement.reset();        
  247.     },
  248.     
  249.     SaveLinkBack : function(url, id, offline) {    
  250.         if (url != ISRIL.sBookmarks.getBookmarkURI( id ).spec) { //changed
  251.             if (!ISRIL.InList(url)) { //resolved url doesn't already exist in saved
  252.                 ISRIL.sBookmarks.changeBookmarkURI( id , ISRIL.uri(url) );
  253.             } else {    
  254.                 //remove unresolved link and don't save new one, also don't sync this old page as read
  255.                 if ( ISRILglobals.ListCache[ id ] ) { ISRILglobals.ListCache[ id ] = false ; }
  256.                 ISRIL.sBookmarks.removeItem( id, true );
  257.                 return false;
  258.             }
  259.             ISRILsync.QueueNew( id , url, ISRILsync.syncTimeIncBatch );
  260.         }
  261.         if (offline) {
  262.             ISRILoffline.addToQueue( id, true );
  263.         }
  264.     },
  265.     
  266.     ResolveLink : function(url, callback, id, offline) {
  267.         ISRIL.channels[ id ] = ISRIL.ios.newChannelFromURI( ISRIL.uri(url) );
  268.         
  269.         // get an listener
  270.         var listener = new ISRIL.listener_linkResolve(callback, url, id, offline);
  271.         
  272.         ISRIL.channels[ id ].notificationCallbacks = listener;
  273.         ISRIL.channels[ id ].asyncOpen(listener, null);
  274.     },
  275.     
  276.     
  277.     
  278.     SaveTabs : function() {
  279.         var num = gBrowser.browsers.length;
  280.         for (var i = 0; i < num; i++) {
  281.           var b = gBrowser.getBrowserAtIndex(i);
  282.           ISRIL.Save( b.currentURI.spec , b.contentTitle );
  283.         }
  284.     },
  285.     
  286.     MarkAsRead : function(id, nogo, service, noSync) {
  287.         if (!id) {
  288.             var Search = ISRIL.findItem();
  289.             id = Search[0];
  290.         }
  291.         service = ( (!service) ? ('') : (service) ); //don't need this anymore
  292.         if (id) {
  293.             var index = ISRIL.sBookmarks.getItemIndex( id ); //only need this if !nogo
  294.             ISRILoffline.deleteOffline( id ); //maybe queue this up and do batches?
  295.             
  296.             if (!noSync) {
  297.                 ISRILsync.QueueUpdate(id, 'read');
  298.             }
  299.             ISRILglobals.noSyncId = id;
  300.             ISRIL.sBookmarks.removeItem(id);
  301.             
  302.             ISRIL.ListSizeInc(-1);
  303.  
  304.             if (!nogo) {                
  305.                 if ( ISRILprefs.pref('mark') == 'close' ) {
  306.                     gBrowser.removeCurrentTab();
  307.                 } else {
  308.                     if (ISRILglobals.ListSize > 0) {
  309.                         switch(ISRILprefs.pref('mark')) {
  310.                             case('next'):     ISRIL.Next(index-1);  break;
  311.                             case('rand'):     ISRIL.RandRead(); break;
  312.                         }
  313.                     }                
  314.                 }
  315.             }            
  316.             
  317.             ISRIL.checkPage(); //this doesn't have to happen to happen on batches, otherwise it's firing a lot!
  318.             
  319.             ISRIL.resolverRemove(id);
  320.         }
  321.     },
  322.     
  323.     autoMark : function() {
  324.         if (ISRILprefs.prefB('autoMark') && !ISRILxul.mark1.hidden) {
  325.             ISRIL.MarkAsRead();
  326.         }
  327.     },
  328.     
  329.     resolverRemove : function(id) {
  330.         try { 
  331.             var sql = "DELETE FROM ril_link_resolver WHERE id = ?1"
  332.             var statement = ISRIL.DB.createStatement(sql);
  333.                 statement.bindInt32Parameter(0, id);
  334.                 statement.execute();
  335.                 statement.reset();
  336.         } catch(err) {}
  337.     },
  338.     
  339.     
  340.     // --- Browser --- //
  341.     
  342.     Open : function(url) {
  343.         openUILinkIn(url, ISRILxul.ButtonTarget?ISRILxul.ButtonTarget.targ:ISRILprefs.pref('open'));
  344.     },
  345.     
  346.     GoTo : function(url, offline, targ, ref) {
  347.         if (offline) { ISRILoffline.curOff = offline; }
  348.         targ = ((targ)?(targ):('current'));
  349.         openUILinkIn(url, targ, null, null, ref?ISRIL.uri(ref):null);
  350.     },
  351.     
  352.     OpenById : function(id) {
  353.         if (id) {
  354.             ISRIL.Open( ISRIL.sBookmarks.getBookmarkURI(id).spec );            
  355.         } else {
  356.             ISRILxul.OpenReadingList(true);
  357.         }
  358.     },
  359.     
  360.     Read : function() {        
  361.         
  362.         if (ISRILglobals.CacheStale) {
  363.             ISRIL.GetList( ISRILxul.Sort.selectedItem.getAttribute('value'), ISRILxul.Filter.value );
  364.         }
  365.         if (!ISRILglobals.ListSize || ISRILglobals.ListSize == 0 || ISRILprefs.pref('read') == 'list' || ISRIL_init.startupError) {
  366.             ISRILxul.ToggleReadingList();    
  367.         } else {
  368.             switch( ISRILprefs.pref('read') ) {
  369.                 case('next'):
  370.                     curUrl = ISRIL.url();
  371.                     var index = -1;
  372.                     if (curUrl) {
  373.                         id = ( (!navigator.onLine && ISRILoffline.curOff) ? (ISRILoffline.curOff):(ISRIL.InList(curUrl)) );
  374.                         if (id) {
  375.                             index = ISRILglobals.ListIndexI[ id ];
  376.                         }
  377.                     }
  378.                     ISRIL.Next( index );
  379.                     break;
  380.                 case('rand'):     ISRIL.RandRead(); break;                
  381.             }
  382.         }
  383.     },
  384.     
  385.     Next : function(index) {
  386.         index = (( (!index && index != 0) || index>=ISRILglobals.ListFilteredSize-1)?(-1):(index));
  387.         var next = ISRILglobals.ListIndexN[ index + 1 ];        
  388.         ISRIL.OpenById( next );
  389.     },
  390.     
  391.     RandRead : function() {
  392.         //need to do the filtered search here too
  393.         if (ISRILglobals.ListFilteredSize > 0) {
  394.             var index = Math.floor(Math.random()*ISRILglobals.ListFilteredSize);
  395.             var next = ISRILglobals.ListIndexN[ index ];
  396.             var r = ISRIL.sBookmarks.getBookmarkURI(next).spec;
  397.             if (r != ISRIL.url() || ISRILglobals.ListSize<=1) {        
  398.                 ISRIL.OpenById( next );
  399.             } else {
  400.                 ISRIL.RandRead();    
  401.             }
  402.         }
  403.     },
  404.     
  405.     // --- //
  406.     
  407.     GoToFeed : function() {
  408.         ISRIL.GoTo('https://readitlaterlist.com/users/'+ISRILsync.feedId());
  409.     },
  410.     online : function(p) {
  411.         p = ((p && p.match(new RegExp('([a-z]+)')))?(p):('unread'));
  412.         ISRIL.GoTo('http://readitlaterlist.com/'+p);
  413.     },
  414.     
  415.     // --- Queries --- //
  416.     
  417.     InList : function(url, checkParsed) {
  418.         //checks for the given url, if it doesn't find it, it parses the url as the server would and tries that
  419.         var marks = PlacesUtils.getBookmarksForURI( ISRIL.uri( url ) );
  420.         for(var i=0; i<marks.length; i++) {
  421.             if ( ISRIL.sBookmarks.getFolderIdForItem( marks[i] ) == ISRILglobals.folderId ) {
  422.                 return marks[i];
  423.             }
  424.         }
  425.         if (!checkParsed) {
  426.             parsed = ISRIL.parseUrl(url);
  427.             if (parsed != url) {
  428.                 return ISRIL.InList(parsed, true);
  429.             }
  430.         }
  431.         return false;
  432.     },
  433.     
  434.     GetList : function(s, filter, reuse) {
  435.         s = ( (!s) ? (11) : (s) );
  436.         if (!reuse || !ISRILglobals.ListResult) {
  437.             filter = ( (!filter) ? (0) : (filter) );
  438.             
  439.             // --  Search Bookmarks -- //
  440.             var options = ISRIL.sHistory.getNewQueryOptions();
  441.             var query = ISRIL.sHistory.getNewQuery();
  442.             query.setFolders([ISRILglobals.folderId], 1);
  443.             
  444.             ISRILglobals.ListResult = ISRIL.sHistory.executeQuery(query, options);
  445.         }
  446.         ISRILglobals.ListResult.sortingMode = s;
  447.  
  448.         var rootNode = ISRILglobals.ListResult.root;
  449.         rootNode.containerOpen = true;
  450.         
  451.  
  452.         // --  Process Results -- //            
  453.         ISRIL.resetCache();
  454.         var l = new Object();
  455.         li = 0; kk = '';
  456.         for (var i = 0; i < rootNode.childCount; i ++) {
  457.               var node = rootNode.getChild(i);
  458.             if (PlacesUtils.nodeIsBookmark(node)) {
  459.                 
  460.                 if (ISRIL.ProcessItem(node, filter)) {
  461.                     l[li] = node;
  462.                     li++;
  463.                 }
  464.                 
  465.             }
  466.             
  467.         }    
  468.  
  469.         // close a container after using it!
  470.         rootNode.containerOpen = false;
  471.         
  472.         // Update unread counter
  473.         ISRILxul.UpdateUnreadCounter();
  474.         
  475.         return l;
  476.     },
  477.     
  478.     ProcessItem : function(node, filter) {        
  479.         rFilter = new RegExp(filter, 'i');
  480.         
  481.         ISRILglobals.ListCache[node.itemId] = node.uri;
  482.         ISRILglobals.ListSize++;
  483.  
  484.         // --  Filter by title, domain, and tag -- //
  485.         if (!filter || filter == ISRILxul.Filter.emptyText || (node.title.match( rFilter ) || node.uri.match( rFilter ) || (node.tags && node.tags.match( new RegExp(filter+'([^,]+)?($|,)', 'i') )))) {
  486.             ISRILglobals.ListIndexN[ISRILglobals.ListFilteredSize] = node.itemId;
  487.             ISRILglobals.ListIndexI[node.itemId] = ISRILglobals.ListFilteredSize;
  488.             ISRILglobals.ResolverIndex[ node.uri ] = {itemId: node.itemId};
  489.             ISRILglobals.ListFilteredSize++;
  490.             return true;
  491.         }
  492.     },
  493.     
  494.     resetCache : function() {
  495.         ISRILglobals.CacheStale = false;
  496.         ISRILglobals.ListIndexN = new Array();
  497.         ISRILglobals.ListIndexI = new Array();
  498.         ISRILglobals.ListCache = new Array();
  499.         ISRILglobals.ResolverIndex = ISRIL.ResolverIndex();
  500.         ISRILglobals.ListSize = 0;
  501.         ISRILglobals.ListFilteredSize = 0;        
  502.     },
  503.     
  504.     rePopCache : function(l) {
  505.         ISRIL.resetCache();
  506.         for(i in l) {
  507.                         
  508.         }
  509.     },
  510.     
  511.     CacheAdd : function(id, url) {
  512.         ISRILglobals.ListCache[ id ] = url;
  513.         ISRILglobals.ResolverIndex[ url ] = {itemId: id};
  514.         ISRILglobals.CacheStale = true;
  515.     },
  516.     
  517.     ListSizeInc : function(i) {
  518.         ISRILglobals.ListSize += i;
  519.         ISRILxul.UpdateUnreadCounter();
  520.     },
  521.     
  522.     ResolverIndex : function() {
  523.         var index = {};
  524.         var sql = "SELECT id, original_url FROM ril_link_resolver"
  525.         var statement = ISRIL.DB.createStatement(sql);
  526.         while (statement.executeStep()) {
  527.             id = statement.getInt32(0);
  528.             url = statement.getUTF8String(1);
  529.                 
  530.             index[ url ] = {itemId: id}
  531.         }
  532.         statement.reset();
  533.         return index;
  534.     },
  535.     
  536.     GetAllFolders : function(folderId, level) {
  537.         var level = ( (!level) ? (0):(level) );
  538.         if (level > 2) { return level; } else { level++; }
  539.         
  540.         var result = PlacesUtils.getFolderContents( ( (!folderId) ? (ISRIL.sBookmarks.bookmarksMenuFolder):(folderId) ) );
  541.         var rootNode = result.root;
  542.  
  543.         // --  Process Results -- //
  544.         var k = 0;
  545.         var folderNodes = new Object();
  546.         for (var i = 0; i < rootNode.childCount; i ++) {
  547.               var node = rootNode.getChild(i);//nodeIsLivemarkContainer
  548.             if (PlacesUtils.nodeIsFolder(node) && !PlacesUtils.nodeIsLivemarkContainer(node)) {
  549.                 folderNodes[k] = {node:node,subs:ISRIL.GetAllFolders(node.itemId, level)};
  550.                 k++;
  551.             }
  552.         }
  553.         return folderNodes;
  554.     },
  555.     
  556.     bookmark : function(bi) { if (bi == 47) { return ISRIL.bookmarkFF() } 
  557.         ISRIL.GoTo( ISRIL_sites[ bi ][1].replace('<URL>', ISRIL.url()).replace('<TITLE>', ISRIL.title()) );
  558.         arr = ISRILprefs.pref('sites').replace( new RegExp('(,)'+bi+'($|,)'), '$2' ).split(',');
  559.         arr[0] = bi;
  560.         if (arr.length > 6) { arr.pop(); }
  561.         ISRILprefs.setPref("sites", ',' + arr.join(',') );
  562.     },
  563.     
  564.     bookmarkFF : function(bi) {
  565.         ISRILxul.closeAnd();
  566.         PlacesUIUtils.showAddBookmarkUI( ISRIL.uri(ISRIL.url()) , ISRIL.title() );
  567.     },
  568.     
  569.     bookmarkMore : function() {
  570.         var bi = ISRILxul.markAndMore.selectedItem.getAttribute('i');
  571.         ISRIL.MarkAsRead(null, null, bi);        
  572.         ISRIL.bookmark( bi );        
  573.     },
  574.     
  575.     // -- SQlite Database -- //
  576.     
  577.     Connect : function() {
  578.         if (!ISRIL.DB) {
  579.             var file = Components.classes["@mozilla.org/file/directory_service;1"]
  580.                     .getService(Components.interfaces.nsIProperties)
  581.                     .get("ProfD", Components.interfaces.nsIFile);
  582.             file.append("ril.sqlite");
  583.             
  584.             ISRIL.DB = ISRIL.sDB.openDatabase(file);
  585.             ISRIL.CreateTables();
  586.             return ISRIL.DB;
  587.         }
  588.     },
  589.     
  590.     CreateTables : function() {
  591.         try {
  592.             ISRIL.DB.executeSimpleSQL("CREATE TABLE ril_sync_queue (id INTEGER,type TEXT, dateUpdated INTEGER, url TEXT, PRIMARY KEY (id,type))");
  593.             ISRIL.DB.executeSimpleSQL("CREATE INDEX type ON ril_sync_queue ( type )");
  594.             ISRIL.DB.executeSimpleSQL("CREATE INDEX dateAdded ON ril_sync_queue ( dateAdded )");
  595.         } catch(e) { }
  596.         try {
  597.             ISRIL.DB.executeSimpleSQL("CREATE TABLE ril_link_resolver (id INTEGER PRIMARY KEY  NOT NULL , original_url VARCHAR)");
  598.         } catch(e) { }
  599.     },
  600.     
  601.     
  602.     // --- Shortcuts --- //
  603.     
  604.     formatKey : function(modifiers, key, keycode) {
  605.         modifiers = ((modifiers)?(modifiers.split(' ').join(' + ') + ' + '):(''));
  606.         return modifiers + ((key)?(key):(keycode));        
  607.     },
  608.     
  609.     NewKey : function(key, oncommand) {
  610.         ISRILxul.removeNode(ISRILxul.bip(key));
  611.                 
  612.         var keySet = ISRILprefs.pref(key).split('||');
  613.         var key = ISRILxul.createNode('key', {id:ISRILxul.dPrefix + key,modifiers:keySet[0],oncommand:oncommand} );
  614.         key.setAttribute( ((keySet[1].length > 1)?('keycode'):('key')) , keySet[1]);
  615.         
  616.         return key;
  617.     },
  618.     
  619.     SetupKeyStrokes : function() {
  620.         keySet = ISRILxul.bi('mainKeyset');
  621.         if (keySet) {
  622.             keySet.appendChild( ISRIL.NewKey('hotkey_toggle', "ISRIL.HotKeyToggle()" ) );
  623.             keySet.appendChild( ISRIL.NewKey('hotkey_push', "ISRIL.HotKeyPush()" ) );
  624.             keySet.appendChild( ISRIL.NewKey('hotkey_open_list', "ISRIL.HotKeyOpenList()" ) );
  625.             keySet.appendChild( ISRIL.NewKey('hotkey_click_mode', "ISRIL.HotKeyClickMode()" ) );
  626.         }
  627.     },
  628.     
  629.     HotKeyToggle : function() {
  630.         ( (!ISRIL.InList(ISRIL.url())) ? (ISRIL.Save()):(ISRIL.MarkAsRead(null)) );
  631.         ISRIL.checkPage();
  632.     },    
  633.     HotKeyPush : function() {
  634.         //act like reading list button was pushed
  635.         return ISRIL.Read();
  636.     },
  637.     HotKeyOpenList : function() {
  638.         //toggle reading list
  639.         ISRILxul.ToggleReadingList();
  640.     },    
  641.     HotKeyClickMode : function() {
  642.         //toggle click save mode
  643.         ( (!ISRIL.CheckNotify()) ? (ISRIL.ClickSaveMode()):(ISRIL.ClickSaveModeOff()) );
  644.     },    
  645.     
  646.     keyCodeConvert : function(c, to) {
  647.         //return ( (!to) ? (String.fromCharCode(c)):(c.toUpperCase().charCodeAt(0)) );
  648.         return c.toUpperCase();
  649.     },
  650.     
  651.     hotkeyText : function(p) {
  652.         var key;
  653.         var keycode;
  654.         var keySet = ISRILprefs.pref('hotkey_'+p).split('||');
  655.         if (keySet[0].length > 1) {
  656.             key = null;
  657.             keycode = keySet[1];
  658.         } else {
  659.             key = keySet[1];
  660.             keycode = null;
  661.         }
  662.         return ISRIL.formatKey( keySet[0], key, keycode );
  663.     },
  664.     
  665.     // --- //
  666.     
  667.     ClickSaveMode : function() { 
  668.         if (!ISRIL.CheckNotify()) { ISRIL.ClickSaveModeOff(); }
  669.         content.document.addEventListener("click", ISRIL.ClickSave, false);        
  670.  
  671.         ISRIL.NotifyClickMode();
  672.     },
  673.     
  674.     ClickSaveModeOff : function() {    
  675.         ISRIL.RemoveNotify();
  676.         content.document.removeEventListener("click", ISRIL.ClickSave, false);
  677.     },
  678.     
  679.     ClickSave : function(e) {
  680.         var targ;
  681.         if (gContextMenu) { a = gContextMenu.target; } else {
  682.             if (!e) var e = window.event;
  683.             if (e.target) targ = e.target;
  684.             else if (e.srcElement) targ = e.srcElement;
  685.             var a = ISRIL.BubbleToTagName(targ, 'A');
  686.             e.preventDefault();
  687.         }
  688.         if (a && (ISRIL.CheckNotify() || gContextMenu) ) {    
  689.         
  690.             if (ISRILprefs.pref('link-checks') != 'no') {
  691.                 newNode = ISRIL.ClickSavedNode();
  692.                 
  693.                 if (e) {
  694.                     X = e.pageX;
  695.                     Y = e.pageY;
  696.                 } else {
  697.                     coords = ISRIL.findPos(a);
  698.                     X = coords[0];
  699.                     Y = coords[1];
  700.                 }
  701.                 newNode.style.left = (X + 10)+"px";
  702.                 newNode.style.top = (Y - 15)+"px";    
  703.             }
  704.             
  705.             var title = ISRIL.strip_tags(a.innerHTML);
  706.             if (title.length == 0) {
  707.                 if (a.firstChild) { //If it doesn't have content then it's probably an image link, so check the image for a title or alt label first
  708.                     if (a.firstChild.title.length > 0) {
  709.                         title = a.firstChild.title;
  710.                     } else if (a.firstChild.alt.length > 0) {
  711.                         title = a.firstChild.title;
  712.                     }
  713.                 }
  714.             }
  715.             
  716.             ISRIL.SaveLink(a.href, title);
  717.         }
  718.     },    
  719.     
  720.     BubbleToTagName : function(obj, tagName) {
  721.         var maxlvls = 10;
  722.         var lvl = 1;
  723.         while (obj.tagName != tagName) {
  724.             if (obj.parentNode) { 
  725.                 obj = obj.parentNode;
  726.             }
  727.             if (lvl >= maxlvls) { return false; }
  728.             lvl++;
  729.         }
  730.         return obj;
  731.     },
  732.     
  733.     ClickSavedNode : function() {        
  734.         var newNode = content.document.createElement('div');
  735.         var id = 'readitlatersaved'+ISRIL.ClickModeNodesN;
  736.         newNode.setAttribute('id', id);
  737.         //newNode.className = 'readitlatersaved';
  738.         newNode.setAttribute('style', 'width:24px;height:24px;position:absolute;font-size:10px;font-weight:bold;color:#000000;background:url(\'chrome://isreaditlater/skin/markfull24.png\');z-index:100000');
  739.         //newNode.innerHTML = 'Saved!';
  740.         content.document.body.appendChild(newNode);
  741.         if (ISRILprefs.pref('link-checks') == 'hide') {
  742.             setTimeout('ISRIL.ClickSavedNodeRemove("'+id+'")', 1500);
  743.         }
  744.         ISRIL.ClickModeNodesN++;
  745.         return newNode;
  746.     },
  747.     
  748.     ClickSavedNodeRemove : function(id) {
  749.         ISRILxul.removeNode(content.document.getElementById(id));
  750.     },
  751.     
  752.     NotifyClickMode : function() {
  753.         
  754.         msg     = ISRIL.l('ClickModeNotify');
  755.         name    = 'ISRILclickmode';
  756.         icon    = 'chrome://isreaditlater/skin/markfull16.png';
  757.         buttons = [{
  758.                     label:  ISRIL.l('TurnOff') + ' ' + '('+ISRIL.hotkeyText('click_mode')+')',
  759.                     popup: null,
  760.                     callback: ISRIL.ClickSaveModeOff,
  761.                       }];
  762.         
  763.         return ISRIL.GetNotify(name, msg, icon, buttons);
  764.     },
  765.     
  766.     // --- Notification Box --- //
  767.     
  768.     GetNotify : function(name, msg, icon, buttons) {        
  769.         var notificationBox = gBrowser.getNotificationBox();
  770.         if (!notificationBox.getNotificationWithValue(name)) {
  771.             return notificationBox.appendNotification(msg, name,
  772.                                icon, notificationBox.PRIORITY_WARNING_MEDIUM, buttons);
  773.         }
  774.     },
  775.     
  776.     CheckNotify : function(name) {
  777.         var name = ( (name)?(name):('ISRILclickmode') );
  778.         var notificationBox = gBrowser.getNotificationBox();
  779.         if (notificationBox.getNotificationWithValue(name)) {
  780.             return notificationBox;
  781.         }
  782.     },
  783.     
  784.     RemoveNotify : function(name) {    
  785.         var notificationBox = ISRIL.CheckNotify();
  786.         if (notificationBox) {
  787.             notificationBox.removeCurrentNotification();
  788.         }
  789.     },
  790.     
  791.     // --- Observers --- //
  792.     
  793.     observe: function(aSubject, topic, data) {
  794.         if (topic == "quit-application-requested") {
  795.             if (ISRILprefs.prefB('feed') && ISRILsync.QueueExists() > 0) {
  796.                 var promptIt = ISRILprefs.prefB('shutdown-prompt');
  797.                 var doIt = ISRILprefs.prefB('shutdown-send');
  798.                 
  799.                 if (promptIt) {
  800.                     var check = {value:false};
  801.                     doIt = ISRILxul.sPrompt.confirmCheck(window, ISRIL.l('ReadItLater'), ISRIL.l('SyncShutdown') , ISRIL.l('DoNotAskAgain'), check );
  802.                     promptIt = !check.value;
  803.                     
  804.                     ISRILprefs.setPref('shutdown-prompt', promptIt);
  805.                     ISRILprefs.setPref('shutdown-send', doIt);
  806.                 }
  807.                 
  808.                 if (doIt) {
  809.                     //stop shutdown
  810.                     aSubject.QueryInterface(Components.interfaces.nsISupportsPRBool);
  811.                     aSubject.data = true;
  812.                     
  813.                     //start syncing, send callback to shutdown when done
  814.                     ISRIL.shutdownWaiting = true;
  815.                     ISRILsync.sendUpdates( 'shutdown' );
  816.                 }
  817.             }
  818.         }
  819.     },
  820.     
  821.     shutdown : function() {
  822.         if (ISRIL.shutdownWaiting) {
  823.             var appStartup = Components.classes['@mozilla.org/toolkit/app-startup;1'].
  824.                         getService(Components.interfaces.nsIAppStartup);
  825.             appStartup.quit( Components.interfaces.nsIAppStartup.eAttemptQuit );
  826.         }
  827.     },
  828.     
  829.     // --- Version Porting --- //
  830.     
  831.     reMapPrefs : function() {
  832.         ISRILprefs.setPrefIfNot("prefsites",     ',6,7,47,19,26,44');
  833.         ISRILprefs.setPrefIfNot("pref_open",     'same');
  834.         ISRILprefs.setPrefIfNot("pref_read",     'rand');
  835.         ISRILprefs.setPrefIfNot("pref_mark",     'go');        
  836.     },    
  837.     
  838.     // --- Localization --- //
  839.     
  840.     l : function(l) {
  841.         return ISRILxul.bip('strings').getString(l);
  842.     },
  843.     
  844.     // --- Service --- //
  845.     
  846.     runBatched: function() {
  847.         this._func.apply(this, this._args);
  848.     },
  849.     
  850.     // --- Utility --- //
  851.     
  852.     note : function(type) { //gets an annotation name for a type
  853.         return ISRIL.appId+"/"+type;
  854.     },
  855.     sortOnSiteName : function(a, b) {
  856.         if (b[1] == '') { return 1; }
  857.         var x = a[0].toLowerCase();
  858.         var y = b[0].toLowerCase();
  859.         return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  860.     },
  861.     whatkeys : function(obj) {
  862.         str = '';
  863.         for(keys in obj) { str += ' | ' + keys; }
  864.         return str;
  865.     },
  866.     arStr : function(obj) {
  867.         str = '';
  868.         for(keys in obj) { str += ' | ' + keys + ':' + obj[keys]; }
  869.         return str;
  870.     },
  871.     now : function() {
  872.         var d = new Date();
  873.         return d.getTime();
  874.     },
  875.     
  876.     B2S : function(bool) {
  877.         return ((bool) ? ('1'):('0'));
  878.     },
  879.     rTrim : function(str, mask) {
  880.         if (str && str.length > 0) {
  881.             return str.substr(0, str.lastIndexOf(mask));
  882.         } return '';
  883.     },
  884.     TrimArray : function(arr) {
  885.         newArr = new Array();
  886.         p = 0;
  887.         for(var i in arr) {
  888.             val = arr[i].replace(/^[\s\r]|[\s\r]$/g, '');
  889.             if (val.length > 0) {
  890.                 newArr[p] = val;
  891.                 p++;
  892.             }
  893.         }
  894.         return arr;
  895.     },
  896.     d : function(str) { if (ISRIL.debug) { return dump(str+"\n"); } },
  897.     strip_tags : function(str){
  898.         return str.replace(/<\/?[^>]+>/gi, '');        
  899.     },
  900.     e : function(str) {
  901.         return encodeURIComponent(str);
  902.     },
  903.     findPos : function (obj) {
  904.         var curleft = curtop = 0;
  905.         if (obj.offsetParent) {
  906.             curleft = obj.offsetLeft
  907.             curtop = obj.offsetTop
  908.             while (obj = obj.offsetParent) {
  909.                 curleft += obj.offsetLeft
  910.                 curtop += obj.offsetTop
  911.             }
  912.         }
  913.         return [curleft,curtop];
  914.     },
  915.     
  916.     t : function() {
  917.         ISRILglobals.t = ISRIL.now();    
  918.         ISRILglobals.ts = ISRIL.now();    
  919.     },
  920.     ts : function(s) {
  921.         ISRIL.d(s + ' = ' + (ISRIL.now() - ISRILglobals.ts) + ' | ' + (ISRIL.now() - ISRILglobals.t));
  922.         ISRILglobals.ts = ISRIL.now();
  923.     },
  924.     
  925.     
  926.     parseUrl : function(url) { 
  927.         if (url) {
  928.             parsed = ISRIL.parseUri(url);
  929.             
  930.             /**********
  931.             Updates to this logic need to be updated in the parse url server side function
  932.             ***********/
  933.             
  934.             parsed.host = parsed.host.toLowerCase().replace('www.', ''); //remove www. and make domain lowercase
  935.             parsed.path = parsed.path.replace(new RegExp('/$'), '');  //remove trailing slash
  936.             
  937.             return parsed.protocol + '://' + parsed.host + parsed.path + parsed.query + ((parsed.anchor)?('#'+parsed.anchor):(''));    
  938.         }
  939.     },
  940.     
  941.     /*
  942.         parseUri 1.2.1
  943.         (c) 2007 Steven Levithan <stevenlevithan.com>
  944.         MIT License
  945.     */
  946.     
  947.         parseUri : function (str) {
  948.             
  949.             var o    = {
  950.                     strictMode: false,
  951.                     key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
  952.                     q:   {
  953.                         name:   "queryKey",
  954.                         parser: /(?:^|&)([^&=]*)=?([^&]*)/g
  955.                     },
  956.                     parser: {
  957.                         strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
  958.                         loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
  959.                     }
  960.                 }
  961.             
  962.             var    m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
  963.                 uri = {},
  964.                 i   = 14;
  965.         
  966.             while (i--) uri[o.key[i]] = m[i] || "";
  967.         
  968.             uri[o.q.name] = {};
  969.             uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
  970.                 if ($1) uri[o.q.name][$1] = $2;
  971.             });
  972.         
  973.             return uri;
  974.         },
  975.         
  976.         
  977.         
  978.         /* --- Listeners --- */
  979.         
  980.         listener_linkResolve : function(callback, url, a, offline) {
  981.             this.c = a;    
  982.             this.callback = callback;
  983.             this.a = a;
  984.             this.url = url;
  985.             this.offline = offline;
  986.             this.maxDataOns = 3;
  987.             this.totalDataOns = 0;
  988.         },
  989.  
  990. }
  991.  
  992. var ISRIL = new ISRILmaster();
  993.  
  994.  
  995. /* --- Listener Prototypes --- */
  996.  
  997. ISRIL.listener_linkResolve.prototype = {
  998.     mData: "",
  999.     
  1000.     // nsIStreamListener
  1001.     onStartRequest: function (aRequest, aContext) {
  1002.     },
  1003.     
  1004.     onDataAvailable: function (aRequest, aContext, aStream, aSourceOffset, aLength) {
  1005.         if (this.totalDataOns < this.maxDataOns) {
  1006.         
  1007.             var scriptableInputStream = 
  1008.               Components.classes["@mozilla.org/scriptableinputstream;1"]
  1009.                 .createInstance(Components.interfaces.nsIScriptableInputStream);
  1010.             scriptableInputStream.init(aStream);
  1011.             
  1012.             this.totalDataOns++;
  1013.         } else {
  1014.             this.onStopRequest(aRequest, aContext);
  1015.         }
  1016.     },
  1017.     
  1018.     onStopRequest: function (aRequest, aContext, aStatus) {
  1019.         if ( ISRIL.channels[this.c] ) {
  1020.             this.callback( ISRIL.channels[this.c].URI.spec , this.a , this.offline );        
  1021.             ISRIL.channels[this.c] = null;
  1022.         }
  1023.     },
  1024.     
  1025.     // nsIChannelEventSink
  1026.     onChannelRedirect: function (aOldChannel, aNewChannel, aFlags) {
  1027.         // if redirecting, store the new channel
  1028.         ISRIL.channels[this.c] = aNewChannel;
  1029.     },
  1030.     
  1031.     // nsIInterfaceRequestor
  1032.     getInterface: function (aIID) {
  1033.         try {
  1034.           return this.QueryInterface(aIID);
  1035.         } catch (e) {
  1036.           throw Components.results.NS_NOINTERFACE;
  1037.         }
  1038.     },
  1039.     
  1040.     // nsIProgressEventSink (not implementing will cause annoying exceptions)
  1041.     onProgress : function (aRequest, aContext, aProgress, aProgressMax) { },
  1042.     onStatus : function (aRequest, aContext, aStatus, aStatusArg) { },
  1043.     
  1044.     // nsIHttpEventSink (not implementing will cause annoying exceptions)
  1045.     onRedirect : function (aOldChannel, aNewChannel) { },
  1046.     
  1047.     // we are faking an XPCOM interface, so we need to implement QI
  1048.     QueryInterface : function(aIID) {
  1049.         if (aIID.equals(Components.interfaces.nsISupports) ||
  1050.             aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
  1051.             aIID.equals(Components.interfaces.nsIChannelEventSink) || 
  1052.             aIID.equals(Components.interfaces.nsIProgressEventSink) ||
  1053.             aIID.equals(Components.interfaces.nsIHttpEventSink) ||
  1054.             aIID.equals(Components.interfaces.nsIStreamListener))
  1055.           return this;
  1056.         
  1057.         throw Components.results.NS_NOINTERFACE;
  1058.     }
  1059. };    
  1060.  
  1061.  
  1062.  
  1063.  
  1064. // --  Bookmark Site Data -- //
  1065.  
  1066. var ISRIL_sites = new Object();
  1067. //UPDATE COUNT HERE FOR RECORD: 48
  1068. ISRIL_sites[47] = new Array( 'Firefox Bookmarks' , '' );
  1069. ISRIL_sites[0] = new Array( 'BlinkBits' , 'http://blinkbits.com/bookmarklets/save.php?v=1&source_url=<URL>&Title=<TITLE>' );
  1070. ISRIL_sites[1] = new Array( 'BlinkList' , 'http://www.blinklist.com/index.php?Action=Blink/addblink.php&Url=<URL>&Title=<TITLE>' );
  1071. ISRIL_sites[2] = new Array( 'Blogmarks' , 'http://blogmarks.net/my/new.php?mini=1&title=<TITLE>&url=<URL>' );
  1072. ISRIL_sites[3] = new Array( 'Buddymarks' , 'http://buddymarks.com/add_bookmark.php?bookmark_title=<TITLE>&bookmark_url=<URL>' );
  1073. ISRIL_sites[4] = new Array( 'CiteUlike' , 'http://www.citeulike.org/posturl?url=<URL>&title=<TITLE>' );
  1074. ISRIL_sites[5] = new Array( 'Connotea' , 'http://www.connotea.org/add?continue=return&uri=<URL>&title=<TITLE>' );
  1075. ISRIL_sites[6] = new Array( 'del.icio.us' , 'http://del.icio.us/post?url=<URL>&title=<TITLE>' );
  1076. ISRIL_sites[7] = new Array( 'Digg it' , 'http://digg.com/submit?phase=2&url=<URL>&title=<TITLE>' );
  1077. ISRIL_sites[37] = new Array( 'Diigo' , 'http://www.diigo.com/post?url=<URL>&title=<TITLE>' );
  1078. ISRIL_sites[39] = new Array( 'DZone' , 'http://www.dzone.com/links/add.html?url=<URL>&title=<TITLE>' );
  1079. ISRIL_sites[8] = new Array( 'Earthlink' , 'http://myfavorites.earthlink.net/my/add_favorite?v=1&url=<URL>&title=<TITLE>" target="_blank' );
  1080. ISRIL_sites[46] = new Array( 'Faves' , 'http://faves.com/Authoring.aspx?u=<URL>&t=<TITLE>' );
  1081. ISRIL_sites[9] = new Array( 'FeedMarker' , 'http://www.feedmarker.com/admin.php?do=bookmarklet_mark&url=<URL>&title=<TITLE>;' );
  1082. ISRIL_sites[10] = new Array( 'Flog this!' , 'http://www.flogz.com/submit?url=<URL>" title="personal finance and investing news website' );
  1083. ISRIL_sites[11] = new Array( 'feedmelinks' , 'http://feedmelinks.com/categorize?from=toolbar&op=submit&name=<TITLE>&url=<URL>' );
  1084. ISRIL_sites[12] = new Array( 'Furl' , 'http://www.furl.net/savedialog.jsp?p=1&u=<URL>&t=<TITLE>&r=&v=1&c=' );
  1085. ISRIL_sites[13] = new Array( 'Give a Link' , 'http://www.givealink.org/cgi-pub/bookmarklet/bookmarkletLogin.cgi?&uri=<URL>&title=<TITLE>' );
  1086. ISRIL_sites[36] = new Array( 'Google' , 'http://www.google.com/bookmarks/mark?op=edit&bkmk=<URL>&title=<TITLE>' );
  1087. ISRIL_sites[14] = new Array( 'Gravee' , 'http://www.gravee.com/account/bookmarkpop?u=<URL>&t=<TITLE>' );
  1088. ISRIL_sites[15] = new Array( 'igooi' , 'http://www.igooi.com/addnewitem.aspx?self=1&noui=yes&jump=close&url=<URL>&title=<TITLE>' );
  1089. ISRIL_sites[16] = new Array( 'Lilisto' , 'http://lister.lilisto.com/?t=<TITLE>&l=<URL>' );
  1090. ISRIL_sites[17] = new Array( 'Linkagogo' , 'http://www.linkagogo.com/go/AddNoPopup?title=<TITLE>&url=<URL>' );
  1091. ISRIL_sites[18] = new Array( 'Linkroll' , 'http://linkroll.com/insert.php?url=<URL>&title=<TITLE>' );
  1092. ISRIL_sites[41] = new Array( 'Looklater' , 'http://api.looklater.com/bookmarks/save?url=<URL>&title=<TITLE>' );
  1093. ISRIL_sites[19] = new Array( 'ma.gnolia' , 'http://ma.gnolia.com/bookmarklet/add?url=<URL>&title=<TITLE>' );
  1094. ISRIL_sites[20] = new Array( 'Maple.nu' , 'http://www.maple.nu/bookmarks/bookmarklet?bookmark[url]=<URL>&bookmark[description]=<TITLE>' );
  1095. ISRIL_sites[45] = new Array( 'Mr. Wong' , 'http://www.mister-wong.de/index.php?action=addurl&bm_url=<URL>&bm_description=<TITLE>' );
  1096. ISRIL_sites[21] = new Array( 'My-Tuts' , 'http://user.my-tuts.com/tag-tutorial/?title=<TITLE>&url=<URL>' );
  1097. ISRIL_sites[38] = new Array( 'Netscape' , 'http://www.netscape.com/submit/?U=<URL>&T=<TITLE>' );
  1098. ISRIL_sites[22] = new Array( 'Netvouz' , 'http://www.netvouz.com/action/submitBookmark?url=<URL>&title=<TITLE>&popup=no' );
  1099. ISRIL_sites[23] = new Array( 'Newsvine' , 'http://www.newsvine.com/_wine/save?popoff=0&u=<URL>&h=<TITLE>' );
  1100. ISRIL_sites[24] = new Array( 'Onlywire' , 'http://www.onlywire.com/b/?u=<URL>&t=<TITLE>;' );
  1101. ISRIL_sites[25] = new Array( 'RawSugar' , 'http://www.rawsugar.com/pages/tagger.faces?turl=<URL>&tttl=<TITLE>' );
  1102. ISRIL_sites[42] = new Array( 'RecommendzIt' , 'http://recommendit.dehsoftware.com/bookmarks.php?action=add&address=<URL>&title=<TITLE>&description=' );
  1103. ISRIL_sites[26] = new Array( 'reddit' , 'http://reddit.com/submit?url=<URL>&title=<TITLE>' );
  1104. ISRIL_sites[27] = new Array( 'Scuttle' , 'http://scuttle.org/bookmarks.php/pass?action=add&address=<URL>&title=<TITLE>' );
  1105. ISRIL_sites[43] = new Array( 'Segnalo' , 'http://segnalo.com/post.html.php?url=<URL>&title=<TITLE>&description=' );
  1106. ISRIL_sites[28] = new Array( 'Shadows' , 'http://www.shadows.com/features/tcr.htm?url=<URL>&title=<TITLE>' );
  1107. ISRIL_sites[29] = new Array( 'Simpy' , 'http://simpy.com/simpy/LinkAdd.do?note=<TITLE>&href=<URL>' );
  1108. ISRIL_sites[30] = new Array( 'Spurl' , 'http://www.spurl.net/spurl.php?url=<URL>&title=<TITLE>' );
  1109. ISRIL_sites[40] = new Array( 'Squidoo' , 'http://www.squidoo.com/lensmaster/bookmark?<URL>' );
  1110. ISRIL_sites[44] = new Array( 'StumbleUpon' , 'http://www.stumbleupon.com/submit?url=<URL>&title=<TITLE>' );
  1111. ISRIL_sites[31] = new Array( 'Taggly' , 'http://taggly.com/bookmarks.php/pass?action=add&address=<URL>' );
  1112. ISRIL_sites[32] = new Array( 'tagtooga' , 'http://www.tagtooga.com/tapp/db.exe?c=jsEntryForm&b=fx&title=<TITLE>&url=<URL>' );
  1113. ISRIL_sites[33] = new Array( 'TalkDigger' , 'http://www.talkdigger.com/index.php?surl=<URL>' );
  1114. ISRIL_sites[34] = new Array( 'Wink' , 'http://www.wink.com/_/tag?url=<URL>&doctitle=<TITLE>' );
  1115. ISRIL_sites[35] = new Array( 'Yahoo MyWeb' , 'http://myweb2.search.yahoo.com/myresults/bookmarklet?t=<TITLE>&u=<URL>' );